package com.newtouch.bxzs.business.train.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.newtouch.bxzs.business.train.mapper.CooperationCompanyMapper;
import com.newtouch.bxzs.business.train.mapper.PerformanceMapper;
import com.newtouch.bxzs.business.train.model.bo.PerformanceBO;
import com.newtouch.bxzs.business.train.model.vo.PerformanceVO;
import com.newtouch.bxzs.business.train.service.PerformanceService;
import com.newtouch.bxzs.common.base.BaseErrorEnum;
import com.newtouch.bxzs.common.base.BaseException;
import com.newtouch.bxzs.common.base.model.CooperationCompany;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.Period;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 机构业绩统计业务层
 * <b>History:</b>
 * <table border="1">
 * <tr>
 * <th>Date</th>
 * <th>Operator</th>
 * <th>Memo</th>
 * </tr>
 * <tr>
 * <td>2021/2/24 13:54</td>
 * <td>wangzhen</td>
 * <td>Create</td>
 * </tr>
 * </table>
 *
 * @author wangzhen
 * @version 1.0.0
 * @since 1.0.0
 */
@Service
public class PerformanceServiceImpl implements PerformanceService {

    private static final int MONTH = 1;
    private static final int ORGANIZATION = 2;
    private static final int INSURANCE = 3;
    private static final int USER = 4;

    @Autowired
    private PerformanceMapper performanceMapper;

    @Autowired
    private CooperationCompanyMapper cooperationCompanyMapper;


    /**
     * (non-Javadoc)
     *
     * @see com.newtouch.bxzs.business.train.service.PerformanceService#getPerformanceInfo(com.newtouch.bxzs.business.train.model.vo.PerformanceVO)
     */
    @Override
    public List<PerformanceBO> getPerformanceInfo(PerformanceVO performanceVO) {
        // 处理入参日期格式
        dealDate(performanceVO);

        // 按照汇总类型查询对应数据
        List<PerformanceBO> performanceBO;
        switch (performanceVO.getPerformanceType()) {
            case MONTH:
                // 月份
                performanceBO = getPerformanceByMonth(performanceVO);
                break;
            case ORGANIZATION:
                // 机构
                performanceBO = getPerformanceByOrganization(performanceVO);
                break;
            case INSURANCE:
                // 保险
                performanceBO = getPerformanceByInsurance(performanceVO);
                break;
            case USER:
                // 用户
                performanceBO = getPerformanceByMember(performanceVO);
                break;
            default:
                throw new BaseException(BaseErrorEnum.REQUEST_PARAMETER_ERROR);
        }
        return performanceBO;
    }
    /**
     * 成员方式查看汇总数据
     *
     * @param performance
     * @return
     */
    private List<PerformanceBO> getPerformanceByMember(PerformanceVO performance) {
        // 转换时间格式 查询业绩
        List<PerformanceBO> performanceBO = null;
        try {
            performanceBO = performanceMapper.getPerformanceByMember(performance.build(),
                    getDate(performance.getStartTime()),
                    getDate(performance.getEndTime()));
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
        return performanceBO;
    }

    /**
     * 保险公司方式查看汇总数据
     *
     * @param performance
     * @return
     */
    private List<PerformanceBO> getPerformanceByInsurance(PerformanceVO performance) {

        List<PerformanceBO> performanceBO = null;
        try {
            performanceBO = performanceMapper.getPerformanceByInsurance(performance.build(),
                    getDate(performance.getStartTime()),
                    getDate(performance.getEndTime()));
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }

        // 查询所有公司信息
        List<CooperationCompany> coList = cooperationCompanyMapper.selectList(new QueryWrapper<>());

        // 获取公司名称的code 和 name 作为map
        Map<String, String> collect = coList.stream().
                collect(Collectors.toMap(CooperationCompany::getUnifiedSocialCreditCode,
                        CooperationCompany::getCooperationCompanyName,
                        (k1, k2) -> k2));

        // 为保险公司中文字段赋值返现
        for (String key : collect.keySet()) {
            for (PerformanceBO p : performanceBO) {
                if (p.getDataSource().equals(key)) {
                    p.setDataSourceName(collect.get(key));
                    break;
                }
            }
        }
        return performanceBO;
    }

    /**
     * 机构方式查看汇总数据
     *
     * @param performance
     * @return
     */
    private List<PerformanceBO> getPerformanceByOrganization(PerformanceVO performance) {
        // 转换时间格式 查询业绩
        List<PerformanceBO> performanceBO = null;
        try {
            performanceBO = performanceMapper.getPerformanceByOrganization(performance.build(),
                    getDate(performance.getStartTime()),
                    getDate(performance.getEndTime()));
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
        return performanceBO;
    }

    /**
     * 年月方式查看汇总数据
     *
     * @param performance
     * @return
     */
    private List<PerformanceBO> getPerformanceByMonth(PerformanceVO performance) {
        // 转换时间格式 查询业绩
        List<PerformanceBO> performanceBO = null;
        try {
            performanceBO = performanceMapper.getPerformanceByMonth(performance.build(),
                    getDate(performance.getStartTime()),
                    getDate(performance.getEndTime()));
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
        return performanceBO;
    }

    /**
     * string转date类型时间
     *
     * @param t
     * @return
     */
    private Date getDate(String t) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return sdf.parse(t);
        } catch (ParseException e) {
            throw new BaseException(e.getMessage());
        }
    }

    /**
     * 获取当月最大天数
     *
     * @param year
     * @param month
     * @return
     */
    private static int getMaxDaysOfOneMonth(int year, int month) {
        int day = 1;
        Calendar cal = Calendar.getInstance();
        cal.set(year, month - 1, day);
        return cal.getActualMaximum(Calendar.DATE);
    }

    /**
     * 格式化数据库格式为 年月日 方便查询数据库
     *
     * @param performanceVO
     */
    private void dealDate(PerformanceVO performanceVO) {
        // 检测入参时间
        this.checkInfo(performanceVO);

        String startTime = performanceVO.getStartTime();
        String endTime = performanceVO.getEndTime();

        String[] start = startTime.split("-");
        String[] end = endTime.split("-");

        // 获取开始和结束时间的最大当月天数
        // 设置当月最大天数 重新设置时间 后续取出使用
        performanceVO.setStartTime(startTime + "-" + getMaxDaysOfOneMonth(Integer.parseInt(start[0]), Integer.parseInt(start[1])));
        performanceVO.setEndTime(endTime + "-" + getMaxDaysOfOneMonth(Integer.parseInt(end[0]), Integer.parseInt(end[1])));
    }

    /**
     * 校验时间范围 判断两时间节点相差月份
     *
     * @param performanceVO
     */
    private void checkInfo(PerformanceVO performanceVO) {
        String startTime = performanceVO.getStartTime() + "-01";
        String endTime = performanceVO.getEndTime() + "-01";
        // 获取开始和结束时间的月数差
        Period between = Period.between(LocalDate.parse(startTime), LocalDate.parse(endTime));

        // 开始和结束时间差值，最大不超过35个月
        long maxYear = 35L;
        long sumYear = between.toTotalMonths();
        if (sumYear > maxYear) {
            throw new BaseException(BaseErrorEnum.REQUEST_METHOD_SUPPORT_ERROR);
        }
    }

}
